/*
 * @Description: 直接播放TTS音频，不存储中间文件
 * @version: 
 * @Author: rfge
 * @Date: 2020-10-28 23:32:41
 * @LastEditors: rfge
 * @LastEditTime: 2023-04-01
 */

#include <fstream>
#include <cstring>
#include <atomic>
#include <unistd.h>
#include <iostream>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <signal.h>
#include <memory>

#include "aikit_biz_api.h"
#include "aikit_constant.h"
#include "aikit_biz_config.h"
#include "tts_interface.h"
#include "simple_kws.h"

using namespace std;
using namespace AIKIT;

static std::atomic_bool ttsFinished(false);
static const char *ABILITY = "e2e44feff";
static int pipe_fd[2]; // 用于管道通信

// KWS相关全局变量
static std::atomic_bool kwsEnabled(false);
static std::string lastDetectedKeyword;

// 前向声明
void TestXTTSWithInterface(const string& text);
void OnKWSError(const char* errorMsg);

// 播放器进程函数
void play_audio() {
    close(pipe_fd[1]); // 关闭写端
    
    // 重定向标准输入到管道读端
    dup2(pipe_fd[0], STDIN_FILENO);
    close(pipe_fd[0]);
    
    // 使用aplay播放16kHz, 16-bit, 单声道PCM数据
    execlp("aplay", "aplay", "-r", "16000", "-f", "S16_LE", "-c", "1", "-t", "raw", NULL);
    
    // 如果执行到这里说明execlp失败了
    cerr << "Failed to start aplay" << endl;
    exit(1);
}

void OnOutput(AIKIT_HANDLE* handle, const AIKIT_OutputData* output) {
    if (output->node->value && output->node->len > 0) {
        // 直接将音频数据写入管道
        write(pipe_fd[1], output->node->value, output->node->len);
    }
}

void OnEvent(AIKIT_HANDLE* handle, AIKIT_EVENT eventType, const AIKIT_OutputEvent* eventValue) {
    if (eventType == AIKIT_Event_End) {
        ttsFinished = true;
        close(pipe_fd[1]); // 关闭管道写端，通知播放器结束
    }
}

void OnError(AIKIT_HANDLE* handle, int32_t err, const char* desc) {
    cerr << "Error occurred: " << err << " - " << desc << endl;
    close(pipe_fd[1]); // 发生错误时也关闭管道
    ttsFinished = true;
}

// KWS回调函数
void OnKeywordDetected(const char* keyword) {
    cout << "\n=== 检测到关键词 ===" << endl;
    cout << "关键词: \"" << keyword << "\"" << endl;

    lastDetectedKeyword = keyword;

    // 根据检测到的关键词执行TTS
    string responseText;
    string keywordStr(keyword);
    if (keywordStr.find("你好") != string::npos || keywordStr.find("小风") != string::npos) {
        responseText = "你好，我是小风语音助手，很高兴为您服务";
    } else if (keywordStr.find("天气") != string::npos) {
        responseText = "今天天气不错，阳光明媚，适合出行";
    } else if (keywordStr.find("时间") != string::npos) {
        responseText = "现在是下午三点二十分";
    } else if (keywordStr.find("音乐") != string::npos) {
        responseText = "好的，正在为您播放音乐";
    } else {
        responseText = "我听到了关键词：" + keywordStr + "，请问需要什么帮助？";
    }

    cout << "回复: " << responseText << endl;
    cout << "===================" << endl;

    // 暂停KWS，播放TTS回复
    simple_kws_stop();

    // 播放TTS回复
    TestXTTSWithInterface(responseText);

    // TTS播放完成后重新启动KWS
    cout << "重新启动关键词识别..." << endl;
    simple_kws_start(OnKeywordDetected, OnKWSError);
}

void OnKWSError(const char* errorMsg) {
    cerr << ">>> KWS错误: " << errorMsg << endl;
}

void TestXTTSWithInterface(const string& text) {
    TTSInterface tts("xiaofeng");
    
    tts.setAudioCallback([](const char* audioData, size_t dataLen) {
        write(pipe_fd[1], audioData, dataLen);
    });
    
    tts.setErrorCallback([](const string& errorMsg) {
        cerr << "TTS Error: " << errorMsg << endl;
        close(pipe_fd[1]);
        ttsFinished = true;
    });
    
    tts.setCompletionCallback([]() {
        close(pipe_fd[1]);
        ttsFinished = true;
    });
    
    if (tts.speak(text)) {
        tts.waitForCompletion();
    } else {
        cerr << "Failed to start TTS" << endl;
        close(pipe_fd[1]);
        ttsFinished = true;
    }
}

void TestXTTS(const string& text) {
    AIKIT_ParamBuilder* paramBuilder = nullptr;
    AIKIT_DataBuilder* dataBuilder = nullptr;   
    AIKIT_HANDLE* handle = nullptr;
    AiText* aiText_raw = nullptr;
    ttsFinished = false;
    
    const char *role = "xiaofeng"; // xiaoyan
    paramBuilder = AIKIT_ParamBuilder::create();
    paramBuilder->clear();
    paramBuilder->param("vcn", role, strlen(role));
    paramBuilder->param("vcnModel", role, strlen(role));
    paramBuilder->param("language", 1);
    paramBuilder->param("textEncoding", "UTF-8", strlen("UTF-8"));
    
    int ret = AIKIT_Start(ABILITY, AIKIT_Builder::build(paramBuilder), nullptr, &handle);
    if (ret != 0) {
        cerr << "AIKIT_Start failed: " << ret << endl;
        goto exit;
    }
    
    dataBuilder = AIKIT_DataBuilder::create();
    dataBuilder->clear();
    aiText_raw = AiText::get("text")->data(text.c_str(), text.length())->once()->valid();
    dataBuilder->payload(aiText_raw);

    ret = AIKIT_Write(handle, AIKIT_Builder::build(dataBuilder));
    if (ret != 0) {
        cerr << "AIKIT_Write failed: " << ret << endl;
        goto exit;
    }

    while (!ttsFinished) {
        usleep(1000);
    }
    
    ret = AIKIT_End(handle);

exit:
    if (paramBuilder != nullptr) {
        delete paramBuilder;
    }
    if (dataBuilder != nullptr) {
        delete dataBuilder;
    }
}

// KWS初始化函数
bool InitKWS(const string& resourcePath = "/demo/resource/many-keywords.txt", int keywordCount = 1) {
    cout << "初始化KWS..." << endl;

    if (simple_kws_init(resourcePath.c_str(), keywordCount) != 0) {
        cerr << "KWS初始化失败" << endl;
        return false;
    }

    cout << "KWS初始化成功" << endl;
    return true;
}

// 启动KWS
bool StartKWS() {
    if (simple_kws_start(OnKeywordDetected, OnKWSError) != 0) {
        cerr << "启动KWS失败" << endl;
        return false;
    }

    kwsEnabled = true;
    cout << "KWS已启动，正在监听关键词..." << endl;
    return true;
}

// 停止KWS
void StopKWS() {
    if (kwsEnabled.load()) {
        simple_kws_stop();
        kwsEnabled = false;
        cout << "KWS已停止" << endl;
    }
}

// 清理KWS资源
void CleanupKWS() {
    simple_kws_cleanup();
    cout << "KWS资源已清理" << endl;
}

void AEE_Init() {
    AIKIT_Configurator::builder()
        .app()
            .appID("bcf15145")
            .apiSecret("NGMzYmI5MTE0MGYzYjk1ODRlMWRhNDA1")
            .apiKey("3a0e16e1a988d976d094b3835dd899e3")
            .workDir("./")
            .resDir("/oem/aikit/resource/")
            .cfgFile("")
        .auth()
            .authType(0)
        .log()
            .logLevel(LOG_LVL_VERBOSE)
            .logMode(LOG_FILE)
            .logPath("../log/xtts_aikit.log");
    int ret = AIKIT_Init();
    if (ret != 0) {
        cerr << "AIKIT_Init failed: " << ret << endl;
        exit(1);
    }
    
    AIKIT_Callbacks cbs = {OnOutput, OnEvent, OnError};
    AIKIT_RegisterAbilityCallback(ABILITY, cbs);
}

int main(int argc, char* argv[]) {
    string default_text = "本文件所有权和解释权归珠海麦塔科技有限公司所有，未经珠海麦塔科技书面许可，任何人不得将本文件的全部或部分转借、复制、抄录、拍照或以其它任何方式向第三方公开。否则，引起有碍所有者版权或商业秘密之问题，将可能承担法律责任。";
    string input_text;
    bool use_interface = false;
    bool enable_kws = false;
    string kws_resource_path = "/demo/resource/many-keywords.txt";
    int kws_keyword_count = 1;
    int text_start_index = 1;

    cout << "=== TTS + KWS 语音交互系统 ===" << endl;
    cout << "支持的参数:" << endl;
    cout << "  --interface    使用新TTS接口" << endl;
    cout << "  --original     使用原始TTS实现" << endl;
    cout << "  --kws          启用关键词识别" << endl;
    cout << "  --kws-resource <path>  指定关键词资源文件" << endl;
    cout << "  --kws-count <num>      指定关键词数量" << endl;
    cout << "=============================" << endl;

    // 解析命令行参数
    for (int i = 1; i < argc; i++) {
        string arg = argv[i];

        if (arg == "--interface") {
            use_interface = true;
            text_start_index = i + 1;
            cout << "Using new TTS interface" << endl;
        } else if (arg == "--original") {
            use_interface = false;
            text_start_index = i + 1;
            cout << "Using original TTS implementation" << endl;
        } else if (arg == "--kws") {
            enable_kws = true;
            text_start_index = i + 1;
            cout << "Enabling keyword recognition" << endl;
        } else if (arg == "--kws-resource" && i + 1 < argc) {
            kws_resource_path = argv[++i];
            text_start_index = i + 1;
            cout << "KWS resource path: " << kws_resource_path << endl;
        } else if (arg == "--kws-count" && i + 1 < argc) {
            kws_keyword_count = atoi(argv[++i]);
            text_start_index = i + 1;
            cout << "KWS keyword count: " << kws_keyword_count << endl;
        } else if (arg.substr(0, 2) != "--") {
            // 这是文本参数
            break;
        } else {
            text_start_index = i + 1;
        }
    }
    
    if (argc > text_start_index) {
        input_text = argv[text_start_index];
        for (int i = text_start_index + 1; i < argc; i++) {
            input_text += " ";
            input_text += argv[i];
        }
        cout << "Using text from command line: " << input_text << endl;
    } else {
        input_text = default_text;
        cout << "No text provided, using default text" << endl;
    }

    // 创建管道
    if (pipe(pipe_fd) == -1) {
        perror("pipe");
        exit(1);
    }

    // 创建播放器子进程
    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(1);
    } else if (pid == 0) {
        // 子进程 - 播放器
        play_audio();
    } else {
        // 父进程 - TTS/KWS主程序
        close(pipe_fd[0]); // 关闭读端

        if (enable_kws) {
            // KWS模式：启动关键词识别，等待用户交互
            cout << "\n进入KWS模式..." << endl;

            // 初始化KWS
            if (!InitKWS(kws_resource_path, kws_keyword_count)) {
                cerr << "KWS初始化失败" << endl;
                close(pipe_fd[1]);
                kill(pid, SIGTERM);
                waitpid(pid, nullptr, 0);
                return 1;
            }

            // 启动KWS
            if (!StartKWS()) {
                cerr << "KWS启动失败" << endl;
                CleanupKWS();
                close(pipe_fd[1]);
                kill(pid, SIGTERM);
                waitpid(pid, nullptr, 0);
                return 1;
            }

            cout << "\n=== 语音交互系统已启动 ===" << endl;
            cout << "说出关键词来触发语音回复" << endl;
            cout << "支持的关键词示例：你好、小风、天气、时间、音乐等" << endl;
            cout << "按Ctrl+C退出" << endl;
            cout << "=========================" << endl;

            // 等待用户交互
            signal(SIGINT, [](int sig) {
                cout << "\n正在退出..." << endl;
                StopKWS();
                CleanupKWS();
                exit(0);
            });

            // 主循环：保持KWS运行
            while (kwsEnabled.load()) {
                sleep(1);

                // 检查KWS状态 - 简化版本不需要复杂的状态检查
            }

            // 清理资源
            StopKWS();
            CleanupKWS();

        } else {
            // 传统TTS模式：播放指定文本
            cout << "\n进入TTS模式..." << endl;

            if (use_interface) {
                // 使用新的TTS接口
                TestXTTSWithInterface(input_text);
            } else {
                // 使用原始TTS实现
                AEE_Init();
                TestXTTS(input_text);
                AIKIT_UnInit();
            }
        }

        // 等待播放器结束
        close(pipe_fd[1]);
        int status;
        waitpid(pid, &status, 0);
    }

    return 0;
}